package com.tanjun.gateway.gatewayservice.config.web;

import com.tanjun.common.exception.BizException;
import com.tanjun.common.exception.ErrCode;
import feign.FeignException;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.support.WebExchangeBindException;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ResponseStatusException;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;

import static com.tanjun.common.enums.err.LoginErrCode.*;

@Component
public class GlobalErrorAttributes extends DefaultErrorAttributes {


    @Override
    public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
        Map<String, Object> errorAttributes = getErrorAttributes(request, options.isIncluded(ErrorAttributeOptions.Include.STACK_TRACE));
        return errorAttributes;
    }

    private Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
        Throwable error = getError(request);
        Map<String, Object> errorAttributes = new LinkedHashMap<>();
        Integer status=500;
        String msg="内部服务异常";
        if(error instanceof BizException){
            ErrCode errCode =((BizException)error).getErrCode();
            if(errCode!=null){
                if (errCode.equals(NOT_LOGIN)) {
                    status = HttpStatus.UNAUTHORIZED.value();
                }
                else if(errCode.equals(NOT_PERMISSION)) {
                   status =HttpStatus.FORBIDDEN.value();
                }
                else if(errCode .equals(NOT_ROLE)){
                    status =HttpStatus.FORBIDDEN.value();
                }
            }
            msg= error.getMessage();
        }
       else if(error instanceof WebExchangeBindException){
            Map<String, String> errors = new HashMap<>();
            ((WebExchangeBindException) error).getAllErrors().forEach((e) -> {
                String fieldName = ((FieldError) e).getField();
                String errorMessage = e.getDefaultMessage();
                errors.put(fieldName, errorMessage);
            });
            msg= errors.values().stream().collect(Collectors.joining(";"));
        }
       else if(error instanceof ResponseStatusException){
           status=500;
           msg=((ResponseStatusException)error).getMessage();
        }
       else if(error instanceof FeignException){
           status=((FeignException)error).status();
           msg=((FeignException)error).getMessage();
        }

        errorAttributes.put("code", status);
        errorAttributes.put("msg", msg);
        errorAttributes.put("isSuccess",false);
        errorAttributes.put("status",status);

        return errorAttributes;
    }



   private String getMsg(Throwable error){
        if(error instanceof BizException){
            return error.getMessage();
        }
        if(error instanceof WebExchangeBindException){
            Map<String, String> errors = new HashMap<>();
            ((WebExchangeBindException) error).getAllErrors().forEach((e) -> {
                String fieldName = ((FieldError) e).getField();
                String errorMessage = e.getDefaultMessage();
                errors.put(fieldName, errorMessage);
            });
            return errors.values().stream().collect(Collectors.joining(";"));
        }
        else {
            return "服务器内部异常";
        }
   }


}
